tmuxを使いこなす / プラグイン開発で機能を拡張
はじめに
こんにちは、中山です。
唐突ですがみなさんtmuxは使われていますか。そう、有名なターミナルの機能を拡張するツールですね。
この種のツールを使っていない方の中には、職場の先輩などに「ちょwターミナル開きすぎwブラクラかよw」などとドヤ顔で言われたことがある方もいらっしゃるのではないでしょうか。かく言う私もドヤ顔でこの種の発言を繰り返していました。
tmuxはデフォルトの機能がかなり豊富なのですが、tpmというプラグインマネージャを使うとさらに機能を拡張することができます。聞いたことがある方も多いのではないでしょうか。ググると検索結果に結構表示されますね。GitHubのtmux-pluginsというorganizationにはさまざまなプラグインがあります。便利なプラグインを紹介しているブログエントリも結構あります。
私はこのプラグインを今まで結構作ってきました。少しシェルスクリプトを書くだけでターミナル上の作業がとても楽になるためです。ただ、プラグインを書こうと思った時にその解説をしているブログはあまり見かけませんでした。簡単に作成できて作業効率が上がるので、もっと多くの人に作ってもらいたいなという気持ちがあります。
という訳で今回はtmuxのプラグイン開発についてドヤ顔でご紹介しようと思います。
概要
「はじめに」でも少し触れましたが、このプラグイン開発かなり簡単です。本当に少しシェルスクリプトを書くだけです。ただ、多少お作法はあるのでそのあたりを中心に解説していこうと思います。
プラグインは以下の二通りのタイプに分けると理解しやすいです。
- キーバインドを追加するタイプ
- ステータスバーに表示するタイプ
まずプラグインの基本的な仕組みを解説した後に、それぞれのタイプについてご紹介します。
プラグインの基本
プラグインの使い方はtpmのREADMEに書いてあるのでそちらを参照してください。以下の文章では、プラグインが動作する仕組みについて解説します。
プラグインはtpmの起動後、 $TMUX_PLUGIN_MANAGER_PATH/<プラグイン名>
以下の *.tmux
というファイルが source
されることにより実行されます。該当のコードはこちらです。
簡単な例を出して解説します。まず、以下のような設定を ~/.tmux.conf
に設定してください。もちろんtpmの設定を済ませた後に実施してください。
set-option -g @plugin 'hoge/tmux-hello-world'
続いて簡易的なプラグインを設置します。以下のコマンドを実行してください。
$ mkdir $TMUX_PLUGIN_MANAGER_PATH/tmux-hello-world; cd $_ $ $EDITOR tmux-hello-world.tmux
プラグインの内容は以下のとおりです。「l(エル)」というキーバインドを追加しています。
#!/usr/bin/env bash tmux bind-key "l" split-window -l 5 "echo Hello, World! | less"
最後に実行権限を付与しましょう。
$ chmod +x tmux-hello-world.tmux
これで準備は完了です。tmuxを再起動して「prefix+l」を押下してみてください。新しいペインが作成され「Hello, World!」と表示されると思います。
簡単ですね。続いてプラグインのタイプ毎に解説していきます。
キーバインドを追加するタイプ
例に出したコードと基本的に同じです。tmuxに新しいキーバインドを追加して、そのキーが押下された時に特定の処理を実行させるタイプのプラグインです。
上記コードを見た方の中には「~/.tmux.confに設定書いておけばよくね」と思った方もいらっしゃるのではないでしょうか。確かにこの機能だけではそのとおりだと思います。しかし、より複雑な動作をさせたい場合、プラグイン化することにより機能毎にファイルを分割できる、というメリットがあります。
具体例を出しましょう。参考にするコードは私が作成したtmux-newline-detectorです。
このプラグインは以下の二つの機能を追加します。詳細はREADMEを参照してください。怪しい英語で解説しています。
機能 | 機能詳細 | デフォルトキーバインド |
---|---|---|
peek | クリップボードの中身をペインに表示させる | Ctrl+P |
paste | クリップボードに改行が含まれている場合、よしなに取り除く | Ctrl+] |
大本となるコードはこちらです。このファイルから各種スクリプトが呼び出されています。ポイントとなるコードは以下の二つです。抜粋します。
tmux bind-key "$(peek_key)" split-window -l 10 "${CURRENT_DIR}/scripts/peek.sh" tmux bind-key "$(paste_key)" run-shell "${CURRENT_DIR}/scripts/paste.sh"
それぞれpeek/paste用のキーバインドを追加しています。上側のコードは split-window
でペインの中で ${CURRENT_DIR}/scripts/peek.sh
を実行させています。下側のコードでは、 run-shell
で ${CURRENT_DIR}/scripts/paste.sh
を実行させています。それぞれのファイルは単なるシェルスクリプトなので、興味があったら中身を確認してみてください。
このように機能毎にファイルを分割させつつ新しいキーバインドを追加できる、というのがこのタイプのプラグインの強みだと思います。
このタイプのプラグイン
いくつかこのタイプに当てはまるプラグインをご紹介します。
- tmux-man
- manなどのドキュメントを確認するコマンドをカレントウィンドウ内で表示させることができます。つまり、ドキュメントを確認するのに別のシェルを立ちあげなくて済むという利点があります。素早くドキュメントを確認しつつ、それを参照しながらコマンドを実行する場合に便利かと思います。
ステータスバーに表示するタイプ
ご存知の方も多いかと思うのですが、tmuxにはステータスバーにさまざまな情報を表示させることができます。例えば、以下のような感じです。
status-right
または status-left
に特定の文字列を設定することで情報を表示させる、というのがこのタイプのプラグインです。参考にするコードはtmux-memです。
このプラグインは #{mem}
という文字列をステータスバーに導入します。これを status-right
または status-left
に設定することで、メモリの使用状況をスタータスバーに表示させるという機能を提供します。
コードを見てみましょう。大本となるコードはこちらです。処理内容は実のところ単純で、特定の文字列(今回の例であれば #{mem}
)を別の文字列に置換し、 tmux set-option
でステータスバーに追加しているだけです。
ポイントとなるコードを以下に抜粋します。10行目のコードです。
do_interpolation() { local string="$1" local interpolated="${string/$mem_interpolation_string/$mem}" echo "$interpolated" }
この関数の中でbash組み込み機能を利用して文字列置換が行われています。それぞれの変数とその値は以下のとおりです。
変数 | 値 |
---|---|
string |
status-right または status-left の内容(例: #[fg=white,bg=black,bold]#{mem}#[default] ) |
mem_interpolation_string |
\#{mem} |
mem |
#($CURRENT_DIR/scripts/mem.sh) |
要するに #{mem}
という文字列をスクリプトの絶対パスに置換しているだけですね。その後22行目のコードで関数(内部的に tmux set-option
を実行している)を呼び出し、ステータスバーに文字列を追加しています。
tmuxのスタータスバーには #(path/to/script)
の形式でスクリプトを実行させる機能があるので、最終的にその実行結果が表示されるというわけです。簡単ですね。
このタイプのプラグイン
- tmux-cpu
- ステータスバーにLAを表示させます。
- tmux-uptime
- ステータスバーにPCの起動時間を表示させます。
tmux-pluginsのリポジトリにもこのタイプのプラグインはたくさんあるので探してみてください。
まとめ
いかがだったでしょうか。本エントリではtmuxの(正確に言うとtpmの)プラグイン開発について解説しました。ほんの少しシェルスクリプトを書くだけで日常作業が劇的に楽になるのはコードを書いていて楽しいです。
なお、私が書いたコードはtmux-pluginsにあるプラグインを参考にしています。開発する際は既存のコードを参照しつつ作成することをおすすめします。みなさんもぜひ一度プラグインの開発に挑戦してみてください。ライフチェンジングな世界が待ち受けていると思います。
本エントリがみなさんの参考になったら幸いに思います。